package com.zx._06_JVM.chapter_01_oom;

import com.zx.common.util.ThreadUtil;
import java.util.Date;
import org.junit.Test;

/**
 * @version v1.0
 * @Title: 演示-内存溢出
 * @Description: -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:// -verbose:gc -Xms20m -Xmx20m
 * @author: zhangxue
 * @date: 2018年9月15日下午9:48:45
 * @company: 未知
 * @Copyright: Copyright (c) 2015
 */
public class D1_OOM {


    private int num01 = 0;
    private int num02 = 0;

    /**
     * StackOverflowError: 模拟大量栈帧
     * -Xss256k  num01=2366
     * 不用设置也行，默认是：num01=18555
     */
    @Test
    public void test01() {
        try {
            run01();
        } catch (Throwable e) {
            System.out.println("StackOverflowError, num01=" + num01);
            e.printStackTrace();
        }
    }

    private void run01() {
        num01++;
        run01();
    }

    /**
     * StackOverflowError: 模拟 单个栈帧超大
     * -Xss256k  num02=233
     * 不用设置也行，默认是：num02=1111
     */
    @Test
    public void test02() {
        try {
            run02();
        } catch (Throwable e) {
            System.out.println("StackOverflowError, num02=" + num02);
            e.printStackTrace();
        }
    }

    private void run02() {
        int a001, a002, a003, a004, a005, a006, a007, a008, a009, a010 = 0;
        int b001, b002, b003, b004, b005, b006, b007, b008, b009, b010 = 0;
        int c001, c002, c003, c004, c005, c006, c007, c008, c009, c010 = 0;
        int d001, d002, d003, d004, d005, d006, d007, d008, d009, d010 = 0;
        int e001, e002, e003, e004, e005, e006, e007, e008, e009, e010 = 0;
        int f001, f002, f003, f004, f005, f006, f007, f008, f009, f010 = 0;
        int g001, g002, g003, g004, g005, g006, g007, g008, g009, g010 = 0;
        int h001, h002, h003, h004, h005, h006, h007, h008, h009, h010 = 0;
        int i001, i002, i003, i004, i005, i006, i007, i008, i009, i010 = 0;
        int j001, j002, j003, j004, j005, j006, j007, j008, j009, j010 = 0;
        num02++;
        run02();
    }

    /**
     * java.lang.OutOfMemoryError: unable to create new native thread
     * -Xms20M -Xmx20M -Xss1g。 需要运行一段时间
     */
    @Test
    public void test03() {
        long a = 0L;
        long last = new Date().getTime();
        while (true) {
            new Thread(() -> {
                ThreadUtil.sleep(60 * 60);
            }).start();
            a++;

            long now = new Date().getTime();
            if (now - last >= 1000) {
                System.out.print("\r" + a);
                // 刷新输出流，确保进度条立即显示
                System.out.flush();
                last = now;
            }

        }
    }

    /**
     * Java.lang.OutOfMemoryError：java heap space
     * -Xms10M -Xmx10M
     */
    @Test
    public void test04() {
        // 根本创建不出，这么大的对象。
        long[][] data = new long[1024][1024 * 1024];
    }

    /**
     * java.lang.OutOfMemoryError:GC overhead limit exceeded
     * -Xms10m -Xmx10m -XX:+PrintGCDetails
     */
    @Test
    public void test05() {
        // 创建一个大数组，用于存放对象引用
        Object[] references = new Object[1096 * 4];
        // 模拟应用程序的工作负载
        while (true) {
            // 填充数组
            for (int i = 0; i < references.length; i++) {
                references[i] = new byte[1024]; // 创建一个1KB的对象
            }

            // 清除数组引用，让对象变得可回收
            for (int i = 0; i < references.length; i++) {
                references[i] = null;
            }
        }
    }

    @Test
    public void test06() {

    }

    @Test
    public void test07() {

    }

    @Test
    public void test08() {

    }
}
